import { useState, useEffect, useCallback, useMemo } from "react";
import { Text, View, TouchableOpacity, useWindowDimensions } from "react-native";
import { useSelector, useDispatch } from "react-redux";
import type { RootState } from "@/store";
import { Col, Row, Grid } from "react-native-easy-grid";
// @ts-ignore
import { ProgressSteps, ProgressStep } from "react-native-progress-steps";

import type { EntryNetworkProps } from "@/router/routerType";
import type { StateType, GridMenuType } from "./type";
import type { DeviceType } from "@/typings/businessType";

import Btn from "@/components/Btn";
import TreeSelect from "@/components/TreeSelect";
import DialogRow, { styles as DialogRowStyles } from "@/components/DialogRow";
import ModalBox from "@/components/ModalBox";
import CustomIcon from "@/components/CustomIcon";

import getDeviceInfo from "@/utils/getDeviceInfo";
import fso from "@/utils/FileOperate/operate";
import { Module } from "@/utils/nativeModules";
import { getEntryNetworkInfo, setEntryNetworkInfo } from "@/utils/entryNetworkInfoOperate";
import { getFmtTime } from "@/utils/date";

import globalMethods from "@/GlobalMethodProvider";
import { setDict } from "@/store/slices/common";
import { deviceAuth, getDictAndDeptList } from "@/api/entryNetwork";
import styles from "./styles";
import { setEntryNetworkInfo as reduxSetEntryNetworkInfo } from "@/store/slices";

import { connect as websocketConnect } from "@/utils/websocket/index";
import config from "@/config";
import { testNetInfo } from "@/api/home";
import { genUUID } from "@/utils";

const defaultScrollViewProps = {
  keyboardShouldPersistTaps: "handled",
  contentContainerStyle: {
    flex: 1,
    justifyContent: "center"
  }
};

/** 入网审核 */
const EntryNetwork = (props: EntryNetworkProps) => {
  const storeRedux = useSelector((state: RootState) => state);

  const [state, _setState] = useState<StateType>({
    deviceInfo: null,
    appInfo: null,
    pixelInfo: null,
    activeStep: 0,
    modalBoxVisible: false,
    dept: null,
    // dept: dept[0],
    deptErrTip: "",
    localhost: null,
    localhostErrTip: "",
    brand: null,
    brandErrTip: "",
    size: null,
    sizeErrTip: "",
    face: null,
    faceErrTip: "",
    playMode: null,
    playModeErrTip: "",
    code: "",
    resultText: ""
  });

  const deptList = useMemo(() => {
    return storeRedux.common.dict?.dept || [];
  }, [storeRedux.common.dict?.dept]);

  // 默认选中的机构
  const defaultSelectedOffice = useMemo(() => {
    if (state.dept) {
      return [state.dept.id];
    } else if (storeRedux.common.dict.dept?.length) {
      return [storeRedux.common.dict.dept[0].id];
    } else {
      return [];
    }
  }, [state.dept, storeRedux.common.dict.dept]);

  // 通用更新状态单个
  const setState = useCallback((field: keyof typeof state, val: any) => {
    _setState(_state => {
      return { ..._state, [field]: val };
    });
  }, []);

  // 通用更新状态(对象)
  const setObjState = useCallback((obj: Partial<typeof state>) => {
    _setState(_state => {
      return { ..._state, ...obj };
    });
  }, []);

  const dispatch = useDispatch();

  const windowDimensions = useWindowDimensions();

  // 获取初始化数据
  const getInitData = useCallback(async () => {
    try {
      fso.info("测试网络连接");
      const testNetRes = await testNetInfo().catch(err => {
        console.log("err: ", err);
      });

      if (props.route.params.flag) {
        const res = await getEntryNetworkInfo();

        if (res) {
          setObjState({
            activeStep: 2,
            code: res.code,
            resultText: `${res.name} 请等待管理员审核`
          });
          // 保存设备信息
          dispatch(reduxSetEntryNetworkInfo(res));

          if (testNetRes) {
            websocketConnect();
          } else {
            globalMethods.$warning("当前没有网络连接, 无法入网", 10 * 1000);
          }
        } else {
          fso.error("本地信息获取获取失败");
        }
      } else {
        const deviceInfo = await getDeviceInfo();
        const appInfo = await Module.getAppInfo();
        const pixelInfo = await Module.getPixel();

        setObjState({
          playMode: {
            label: deviceInfo.isLandscape ? "竖屏" : "横屏",
            value: deviceInfo.isLandscape ? "1" : "2"
          },
          deviceInfo,
          appInfo,
          pixelInfo
        });

        if (testNetRes) {
          const res = await getDictAndDeptList();
          console.log("字典数据: ", res.data);
          // 保存字典和机构数据
          dispatch(setDict(res.data || {}));
        } else {
          globalMethods.$warning("当前没有网络连接, 无法获取入网数据, 请连接网络后重试", 10 * 1000);
        }
      }
    } catch (err) {
      if (err instanceof Error) {
        globalMethods.$error("获取初始化数据失败: " + err.message);
      } else {
        globalMethods.$error("获取初始化数据失败: " + err);
      }
    }
  }, [dispatch, props.route.params.flag, setObjState]);

  useEffect(() => {
    getInitData();

    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [storeRedux.common.networkState]);

  const openModalBox = () => {
    if (!state.dept) {
      setObjState({
        modalBoxVisible: true,
        // @ts-ignore
        dept: storeRedux.common.dict?.dept?.[0] || null
      });
    } else {
      setState("modalBoxVisible", true);
    }
  };
  const hideModalBox = () => setState("modalBoxVisible", false);

  /** 提交 */
  const handleSubmit = async () => {
    try {
      let flag = true;

      if (!state.dept) {
        flag = false;
        setObjState({ deptErrTip: "请选择机构" });
      }

      // 检验数据是否已选择
      [...leftMenu, ...rightMenu].forEach(e => {
        const value = state[e.valueKey];
        if (!value) {
          setObjState({
            [e.errorTipKey]: "请选择" + e.label
          });
          flag = false;
        }
      });

      if (!flag) {
        globalMethods.$warning("请填写相关信息");
        return;
      }

      const deviceInfo = state.deviceInfo;
      if (!deviceInfo) {
        globalMethods.$warning("没有获取到设备信息, 请点击刷新按钮后重试");
        return;
      }

      if (!state.appInfo) {
        globalMethods.$warning("没有获取到APP信息, 请点击刷新按钮后重试");
        return;
      }

      const pixelInfo = state.pixelInfo;
      if (!pixelInfo) {
        globalMethods.$warning("没有获取到分辨率信息, 请点击刷新按钮后重试");
        return;
      }

      globalMethods.$showLoading("设备认证中");

      console.log("认证的设备数据", state);

      const uuid = genUUID();

      // 新增的设备信息
      const addDeviceInfo: DeviceType = {
        uuid,
        officeName: state.dept?.name || "",
        officeCode: state.dept?.code || "",
        area: state.localhost?.label || "",
        factory: state.brand?.label || "",
        intoNetworkTime: getFmtTime(),
        model: `${state.size?.label || ""}_${state.face?.label || ""}`,
        mac: deviceInfo.mac,
        ip: deviceInfo.ip || "",
        androidId: deviceInfo?.androidId || Date.now().toString(),
        systemVersion: `${deviceInfo.systemName} ${deviceInfo.systemVersion}`,
        resolutionRatio: `${pixelInfo.width}*${pixelInfo.height}`,
        softwareVersion: state.appInfo?.versionName || "",
        playMode: deviceInfo?.isLandscape ? "1" : "2",
        name: `${state.dept?.name}_${state.localhost?.label}_${state.brand?.label}_${state.size?.label}`,
        status: "3",
        code: state.code,
        remarks: ""
      };

      fso.info("入网审核, 设备信息 -> ", addDeviceInfo);

      const addDeviceRes = await deviceAuth(addDeviceInfo);
      console.log("设备新增成功: ", addDeviceRes);
      // globalMethods.$success("数据提交成功");

      const entryNetworkInfo = {
        ...addDeviceInfo,
        code: addDeviceRes.data
      };

      // 保存入网信息
      const res = await setEntryNetworkInfo(entryNetworkInfo);
      dispatch(reduxSetEntryNetworkInfo(entryNetworkInfo));

      if (!res) {
        fso.warn("入网审核的信息保存失败");
      }

      setObjState({
        activeStep: state.activeStep + 1,
        code: addDeviceRes.data,
        resultText: `${addDeviceInfo.name} 请等待管理员审核`
      });

      websocketConnect();
    } catch (err: any) {
      console.log("err: ", err);
      if (err instanceof Error) {
        globalMethods.$error("发生了错误: " + err.message);
      } else {
        globalMethods.$error("发生了错误: " + err.msg || "");
      }
    } finally {
      globalMethods.$hideLoading();
    }
  };

  const TriangleComp = () => <View style={[DialogRowStyles.triangle, { borderTopColor: "#6e6e6e" }]} />;

  /** 左边菜单数据 */
  const leftMenu = useMemo(() => {
    const menu: GridMenuType = [
      {
        label: "设备尺寸",
        title: "请选择设备尺寸",
        placeholder: "请选择设备尺寸",
        items: storeRedux.common.dict.m180_size || [],
        valueKey: "size",
        errorTipKey: "sizeErrTip"
      },
      {
        label: "播放方式",
        title: "请选择播放方式",
        placeholder: "请选择播放方式",
        items: storeRedux.common.dict.m180_play_mode || [],
        valueKey: "playMode",
        errorTipKey: "playModeErrTip"
      }
    ];

    return menu;
  }, [storeRedux.common.dict.m180_play_mode, storeRedux.common.dict.m180_size]);

  /** 右边菜单数据 */
  const rightMenu = useMemo(() => {
    const menu: GridMenuType = [
      {
        label: "所属区域",
        title: "请选择所属区域",
        placeholder: "请选择所属区域",
        items: storeRedux.common.dict.m180_area || [],
        valueKey: "localhost",
        errorTipKey: "localhostErrTip"
      },
      {
        label: "单 双 面",
        title: "请选择单双面",
        placeholder: "请选择单双面",
        items: storeRedux.common.dict.m180_face || [],
        valueKey: "face",
        errorTipKey: "faceErrTip"
      },
      {
        label: "设备厂家",
        title: "请选择设备厂家",
        placeholder: "请选择设备厂家",
        items: storeRedux.common.dict.m180_factory || [],
        valueKey: "brand",
        errorTipKey: "brandErrTip"
      }
    ];
    return menu;
  }, [storeRedux.common.dict.m180_area, storeRedux.common.dict.m180_face, storeRedux.common.dict.m180_factory]);

  return (
    <View style={styles.container}>
      <View style={styles.progressContainer}>
        <ProgressSteps activeStep={state.activeStep}>
          <ProgressStep label="设备入网信息" scrollViewProps={defaultScrollViewProps} removeBtnRow>
            <View style={styles.itemContainer}>
              <Grid style={{ flex: 1 }}>
                <Col>
                  <Row style={styles.item}>
                    <Text>
                      <Text style={styles.requiedText}>*</Text>
                      所属机构:
                    </Text>
                    <View style={[styles.pick, styles.deptPick]}>
                      <Btn
                        type="info"
                        text={state.dept ? state.dept.name : "请选择所属机构"}
                        containerStyle={[
                          styles.deptBtnContainer,
                          { borderColor: state.deptErrTip ? "#f56c6c" : "#ccc" }
                        ]}
                        btnTextStyle={[styles.deptBtn, { fontWeight: state.dept ? "bold" : "normal" }]}
                        rightComponent={TriangleComp}
                        onClick={openModalBox}
                      />
                      {state.deptErrTip && <Text style={styles.deptErrTip}>{state.deptErrTip}</Text>}
                    </View>
                  </Row>

                  {/* 左边菜单 */}
                  {leftMenu.map((e, i) => {
                    return (
                      <Row style={styles.item} key={i}>
                        <Text>
                          <Text style={styles.requiedText}>*</Text>
                          {e.label}:
                        </Text>
                        <View style={styles.pick}>
                          <DialogRow
                            type="select"
                            title={e.title}
                            placeholder={e.placeholder || e.title}
                            items={e.items}
                            errorTip={state[e.errorTipKey] || ""}
                            selectedId={state[e.valueKey]?.value || ""}
                            selectedValue={item => {
                              if (item && !Array.isArray(item)) {
                                setObjState({
                                  [e.valueKey]: item,
                                  [e.errorTipKey]: ""
                                });
                              }
                            }}
                          />
                        </View>
                      </Row>
                    );
                  })}
                </Col>

                <Col>
                  {/* 右边菜单 */}
                  {rightMenu.map((e, i) => {
                    return (
                      <Row style={styles.item} key={i}>
                        <Text>
                          <Text style={styles.requiedText}>*</Text>
                          {e.label}:
                        </Text>
                        <View style={styles.pick}>
                          <DialogRow
                            type="select"
                            title={e.title}
                            placeholder={e.placeholder || e.title}
                            items={e.items}
                            errorTip={state[e.errorTipKey] || ""}
                            selectedId={state[e.valueKey]?.value || ""}
                            selectedValue={item => {
                              if (item && !Array.isArray(item)) {
                                setObjState({
                                  [e.valueKey]: item,
                                  [e.errorTipKey]: ""
                                });
                              }
                            }}
                          />
                        </View>
                      </Row>
                    );
                  })}
                </Col>
              </Grid>

              <View style={styles.tipContainer}>
                <View>{state.appInfo && <Text>软件版本: {state.appInfo.versionName}</Text>}</View>

                <View>
                  {state.deviceInfo && (
                    <>
                      <Text>
                        设备信息: {state.deviceInfo.systemName} {state.deviceInfo.systemVersion}{" "}
                        <Text style={styles.green}>{state.deviceInfo.isLandscape ? "横屏" : "竖屏"}</Text>状态
                      </Text>
                      <Text>IP地址: {state.deviceInfo.ip}</Text>
                      <Text>MAC地址: {state.deviceInfo.mac}</Text>
                    </>
                  )}

                  {state.pixelInfo && (
                    <Text>
                      设备分辨率: {state.pixelInfo.width}*{state.pixelInfo.height}
                    </Text>
                  )}
                </View>
              </View>

              <View style={styles.btnContainer}>
                <TouchableOpacity style={{ padding: 6 }} onPress={getInitData}>
                  <CustomIcon name="icon-Sync" size={28} />
                </TouchableOpacity>
                <Btn text="申请认证" type="primary" onClick={handleSubmit} />
                {config.IS_DEBUG && (
                  <>
                    <Btn
                      text="查看本地保存的入网信息"
                      type="primary"
                      onClick={() => {
                        getEntryNetworkInfo()
                          .then(res => {
                            console.log("res: ", res);
                          })
                          .catch(err => {
                            console.log("err: ", err);
                          });
                      }}
                    />
                    <Btn
                      text="跳转播放页"
                      type="primary"
                      onClick={() => {
                        props.navigation.navigate("VideoDisplay");
                      }}
                    />
                  </>
                )}
              </View>
            </View>
          </ProgressStep>
          <ProgressStep label="审核结果" scrollViewProps={defaultScrollViewProps} removeBtnRow>
            <View style={[styles.itemContainer, { justifyContent: "center", alignItems: "center" }]}>
              <Text style={{ fontSize: 24 }}>设备编号: {state.code}</Text>
              <Text style={{ fontSize: 24 }}>{state.resultText}</Text>
            </View>
          </ProgressStep>
        </ProgressSteps>
      </View>

      <ModalBox
        title="请选择所属机构"
        width="50%"
        visible={state.modalBoxVisible}
        onClose={hideModalBox}
        onConfirm={hideModalBox}
        onDismiss={hideModalBox}
        // dismissable={false}
        hideConfirmBtn
        closeBtnText="关闭"
        contentPosition="center"
      >
        <View
          style={[
            styles.deptModalContainer,
            {
              height: windowDimensions.height * 0.6,
              width: "100%"
            }
          ]}
        >
          <Text style={styles.deptModalText}>
            当前选择:
            <Text style={styles.deptModalValue}> {state.dept?.name}</Text>
          </Text>
          <TreeSelect
            // @ts-ignore
            data={deptList}
            defaultSelectedId={defaultSelectedOffice}
            change={val => {
              if (val.item) {
                setObjState({
                  dept: val.item,
                  deptErrTip: "",
                  modalBoxVisible: false
                });
              }
            }}
          />
        </View>
        <Text style={styles.deptSelectTip}>TIP: 内容可以点击展开, 上下滑动</Text>
      </ModalBox>
    </View>
  );
};

export default EntryNetwork;
